#include <boost/test/unit_test.hpp>
#include "Mutex.hpp"
#include <iostream>

//TODO: refaire avec les BOOSTCHECK
BOOST_AUTO_TEST_CASE(simple_mutex)
{
	Mutex *m = new Mutex();
	BOOST_CHECK(m->Lock());
	BOOST_CHECK(m->UnLock());

	delete m;
}

BOOST_AUTO_TEST_CASE(simple_trylock)
{
	Mutex *m = new Mutex();
	BOOST_CHECK(m->Lock());

	BOOST_CHECK(!m->TryLock());
	BOOST_CHECK(m->UnLock());
	BOOST_CHECK(m->TryLock());
	BOOST_CHECK(m->UnLock());

	delete m;
}

BOOST_AUTO_TEST_CASE(multiple_mutex_state)
{
	Mutex *m = new Mutex();
	Mutex *m1 = new Mutex();
	Mutex *m2 = new Mutex();
	
	BOOST_CHECK(m->Lock());
	BOOST_CHECK(m1->Lock());
	BOOST_CHECK(m2->Lock());

	BOOST_CHECK(m->GetState() == eLock);
	BOOST_CHECK(m1->GetState() == eLock);
	BOOST_CHECK(m2->GetState() == eLock);
	
	BOOST_CHECK(!m->TryLock());
	BOOST_CHECK(!m1->TryLock());
	BOOST_CHECK(!m2->TryLock());
	
	BOOST_CHECK(m->UnLock());
	BOOST_CHECK(m1->UnLock());
	BOOST_CHECK(m2->UnLock());

	BOOST_CHECK(m->GetState() == eUnlock);
	BOOST_CHECK(m1->GetState() == eUnlock);
	BOOST_CHECK(m2->GetState() == eUnlock);

	delete m,m1,m2;
}


BOOST_AUTO_TEST_CASE(mutex_errors)
{
	Mutex *m = new Mutex();
	Mutex *m1 = new Mutex();
	
	BOOST_CHECK(m->Lock());
	//BOOST_CHECK(!m->Lock());//deadlock
	BOOST_CHECK(m->UnLock());
	BOOST_CHECK(!m->UnLock());

	BOOST_CHECK(m->TryLock());
	BOOST_CHECK(!m->TryLock());
	BOOST_CHECK(m->UnLock());

	delete m; //can delete object while unlock

	BOOST_CHECK(m1->Lock());

	delete m1; //can delete object while lock 
}